// import React from 'react';
// import ReactDOM from 'react-dom';
import React from './react';
import ReactDOM from './react-dom';
import { updateQueue } from './Component'

/**
 * 元素在react上是一个虚拟Dom元素，实质是一个JS对象，描述了页面上展示的内容。
 */

/**
 * 1. jsx语法：
 * 在webpack的时候会被编译成createElement，打包后的代码在浏览器执行时会执行createElement函数，然后返回一个JS对象(虚拟DOM)。
 * const ele1 = <h1>hello react</h1>
 * 如果父元素内是纯文本，则会被处理成一个整体的文本元素，即'hello react'；
 * const ele2 = <h1>hello <span>sssss</span> react</h1>
 * 如果文本中间穿插其他标签，则会被处理成多个分割的文本元素, 即'hello', span, 'react'。
 */

// const ele = React.createElement('h1', {
//   id: 'title',
// }, 'hello react')
/**
 * render方法负责将虚拟DOM插入容器中
 */  
// ReactDOM.render(ele, document.getElementById('root'))

const timeEle = (
  <div>
    <h1>render实现</h1>
    <div style={{color: 'red'}}>现在是</div>
    <span>{ new Date().toLocaleTimeString() }</span>
  </div>
)
// ReactDOM.render(timeEle, document.getElementById('root'))

/**
 * react元素是不可变的(不可以修改/添加属性，Object.freeze())，且只会更新必要的部分。
 */
function tick() {
  const ele = (
    <div>
      <div style={{color: 'red'}}>现在是</div>
      <span>{ new Date().toLocaleTimeString() }</span>
    </div>
  )
  ReactDOM.render(ele, document.getElementById('root'))
}
// setInterval(tick, 1000) // 页面中会渲染一个时间,且只有span元素更新

/**
 * 函数(自定义)组件
 * @param {*} props 
 * @returns 
 */
function ChildrenComponent(props) {
  return (
    <div>
      i'm ChildrenComponent
    </div>
  )
}

function FatherComponent(props) {
  return (
    <div className='title' style={{ backgroundColor: 'pink', color: 'yellow' }}>
      <h1>hello, { props.name }</h1>
      { props.children }
      <ChildrenComponent />
    </div>
  )
}
// ReactDOM.render(
//   (
//     <FatherComponent name="react">
//       <span>i'm FatherComponent</span>
//     </FatherComponent>
//   ), 
//   document.getElementById('root')
// )

/**
 * 1. 类组件
 * 可以且只能在构造函数中给this.state赋值；父组件提供的属性对象是只读的，不能修改。
 * 2. 合成事件和批量更新
 * 在react里，事件更新是批量的，调用setState之后状态不会立即更新，而是先缓存，等事件处理函数完成后，再一次性批量更新，重新渲染。
 * 若超出了react的jsx原生事件处理函数，就是立即更新，如setTimeout、promide.then()
 */
class Counter extends React.Component{
  constructor(props) {
    super(props)
    this.state = {
      number: 0,
      name: this.props.name
    }
  }
  handleClick = () => {
    updateQueue.isBatchingUpdate = true
    this.setState({ number: this.state.number + 1 })
    console.log("@@@ ~ Counter ~ this.state.number", this.state.number)
    this.setState({ number: this.state.number + 1 })
    console.log("@@@ ~ Counter ~ this.state.number", this.state.number)
    
    // this.setState((lastState) => ({
    //   number: lastState.number + 1
    // }), () => {
    //   console.log(this.state.number);
    // })
    // setTimeout(() => {
    //   this.setState({ number: this.state.number + 1 })
    //   console.log("@@@ ~ Counter ~ setTimeout ~ this.state.number", this.state.number)
    //   this.setState({ number: this.state.number + 1 })
    //   console.log("@@@ ~ Counter ~ setTimeout ~ this.state.number", this.state.number)
    // }, 1000)
    // 上述 setTimeout 等效于
    // queueMicrotask(() => {
    //     this.setState({ number: this.state.number + 1 })
    //     console.log("@@@ ~ Counter ~ setTimeout ~ this.state.number", this.state.number)
    //     this.setState({ number: this.state.number + 1 })
    //     console.log("@@@ ~ Counter ~ setTimeout ~ this.state.number", this.state.number)
    //   }
    // )
    updateQueue.batchUpdate()
  }
  render() {
    return (
      <div>
        <p>{ this.state.name }</p>
        <p>{ this.state.number }</p>
        <button onClick={ this.handleClick }>plus</button>
      </div>
    )
  }
}
ReactDOM.render(<Counter name='计数器' />, document.getElementById('root'))

/**
 * 合成事件和批量更新
 * 在react里，事件更新
 */